package com.controller;


import com.vo.FileVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.InputStreamSource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartResolver;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

@Controller
public class FileController {
    @Autowired(required = false)
    private List<MultipartResolver> resolvers;

    @RequestMapping("/")
    public String index() {
        return "index";
    }

    /**
     * 方法的参数类型是MultipartFile
     * 参数名跟表单file控件的名字一样
     *
     * @param myFile
     * @return
     */
    @RequestMapping("/upload")
    public String upload(MultipartFile myFile) {
        //要用Path（java.nio),不能用File，因为jetty下会报文件找不到的异常
        Path path = Paths.get("D:\\temp", myFile.getOriginalFilename());
        try {
            myFile.transferTo(path);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "index";
    }

    @RequestMapping("/upload2")
    public String upload2(MultipartFile[] myFiles) {
        for (MultipartFile myFile : myFiles) {
            Path path = Paths.get("D:\\temp", myFile.getOriginalFilename());
            try {
                myFile.transferTo(path);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return "index";
    }

    @RequestMapping("/upload3")
    public String upload3(List<MultipartFile> myFiles) {
        for (MultipartFile myFile : myFiles) {
            Path path = Paths.get("D:\\temp", myFile.getOriginalFilename());
            try {
                myFile.transferTo(path);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return "index";
    }

    @RequestMapping("/uploadForAjax")
    @ResponseBody
    public String uploadForAjax(MultipartFile myFile, String name) {
        System.out.println("额外的表单数据:" + name);
        Path path = Paths.get("D:\\temp", myFile.getOriginalFilename());
        try {
            myFile.transferTo(path);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "upload ok";
    }

    @RequestMapping("/uploadForAjax2")
    @ResponseBody
    public String uploadForAjax2(FileVO fileVO) {
        System.out.println("额外的表单数据:" + fileVO.getName());
        MultipartFile myFile = fileVO.getMyFile();
        Path path = Paths.get("D:\\temp", myFile.getOriginalFilename());
        try {
            myFile.transferTo(path);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "upload ok";
    }


    /**
     * Entity是html中的一个术语，表示头（header）和体（body）
     * RepsoneEntity代表着http的一个完整响应内容
     * <p>
     * InputStreamSource就是一个InputStream的源头，
     * 为什么是输入流？因为mvc框架需要读取数据之后再响应给浏览器
     *
     * @return
     */
    @RequestMapping("/download")
    public ResponseEntity<InputStreamSource> download(String filename) {

        String path = "E:\\Image\\" + filename;
        InputStreamSource source = new FileSystemResource(path);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(getMediaType(filename));
        try {
            //让浏览器以附件的方式来下载文件，而不是直接打开，
            // 并解决另存为对话框名字的乱码问题
            headers.setContentDispositionFormData("attachment", URLEncoder.encode(filename, "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        ResponseEntity<InputStreamSource> responseEntity = new ResponseEntity<>(source, headers, HttpStatus.OK);

        return responseEntity;

    }

    /**
     * 基于文件名来得到对应的MediaType
     *
     * @param filename
     * @return
     */
    private MediaType getMediaType(String filename) {
        //guessContentTypeFromName是从文件名猜测其内容类型，如果为null就猜测失败
        String midiaType = URLConnection.guessContentTypeFromName(filename);
        if (midiaType == null) {
            midiaType = MediaType.APPLICATION_OCTET_STREAM_VALUE;
        }
        // 不要直接实例化MediaType，而要用parseMediaType方法
        // 因为直接实例化对/符号没有进行转意操作
        return MediaType.parseMediaType(midiaType);
    }
}
